import logging
from datetime import datetime, timedelta
from django.db.models import Count, Sum, F, Q
from django.utils import timezone

from enterprise.models import Job, CCompany, Recruiter
from Login.models import User
# from chatmessage.models import ChatMessage
from violation.models import JobAuditRecord, Violation
from datastats.models import DataStats

logger = logging.getLogger(__name__)


class StatsService:
    """数据统计核心服务"""

    @classmethod
    def _get_date_range(cls, period, stats_date):
        """根据统计周期获取时间范围"""
        if period == 1:  # 日统计：当天00:00-23:59
            start_date = datetime.combine(stats_date, datetime.min.time())
            end_date = datetime.combine(stats_date, datetime.max.time())
        elif period == 2:  # 周统计：周一00:00-周日23:59（按中国周计算）
            # 获取当周周一（stats_date为周日，往前推6天）
            monday = stats_date - timedelta(days=stats_date.weekday())
            start_date = datetime.combine(monday, datetime.min.time())
            end_date = datetime.combine(stats_date, datetime.max.time())
        elif period == 3:  # 月统计：当月1号00:00-月底23:59
            start_date = datetime(stats_date.year, stats_date.month, 1, 0, 0, 0)
            # 计算当月最后一天
            next_month = stats_date.replace(month=stats_date.month + 1) if stats_date.month < 12 else datetime(
                stats_date.year + 1, 1, 1)
            end_date = datetime.combine(next_month - timedelta(days=1), datetime.max.time())
        return timezone.make_aware(start_date), timezone.make_aware(end_date)

    @classmethod
    def calculate_business_stats(cls, period, stats_date):
        """计算业务指标"""
        start_time, end_time = cls._get_date_range(period, stats_date)

        # 1. 职位相关统计
        job_stats = {
            "新增职位数": Job.objects.filter(created_at__range=(start_time, end_time)).count(),
            "已发布职位数": Job.objects.filter(status='published', created_at__range=(start_time, end_time)).count(),
            "违规下架职位数": Job.objects.filter(status='closed', updated_at__range=(start_time, end_time)).count(),
            # 各行业职位分布（基于公司行业）
            "行业分布": dict(Job.objects.filter(created_at__range=(start_time, end_time)).values(
                "company__industry").annotate(count=Count("id"))),
            # 各薪资段分布
            "薪资段分布": dict(Job.objects.filter(created_at__range=(start_time, end_time)).values(
                "salary_range").annotate(count=Count("id")))
        }

        # 2. 企业相关统计
        company_stats = {
            "新增企业数": CCompany.objects.filter(created_at__range=(start_time, end_time)).count(),
            "活跃企业数": CCompany.objects.filter(
                Q(job__created_at__range=(start_time, end_time)) & Q(job__status='published')
            ).distinct().count(),
            "高违规企业数": CCompany.objects.filter(
                job__status='closed', job__updated_at__range=(start_time, end_time)
            ).annotate(violation_count=Count("job")).filter(violation_count__gte=3).count()
        }

        # 3. 求职者相关统计
        # 活跃求职者：通过ChatMessage的user_id统计（注意：ChatMessage.user_id是BigIntegerField，不是外键）
        # active_user_ids = ChatMessage.objects.filter(
        #     send_time__range=(start_time, end_time),
        #     sender_type=2  # 2=求职者发送
        # ).values_list('user_id', flat=True).distinct()
        
        user_stats = {
            "新增求职者数": User.objects.filter(
                user_type='jobseeker', created_at__range=(start_time, end_time)
            ).count(),
            # 活跃求职者数：统计在指定时间段内发送过消息的求职者数量
            # "活跃求职者数": len(active_user_ids),
            # 简历投递量：当前项目中暂无简历投递模型，暂时设为0
            "简历投递量": 0  # 待后续添加简历投递模型后实现
        }

        return {**job_stats, **company_stats, **user_stats}

    @classmethod
    def calculate_compliance_stats(cls, period, stats_date):
        """计算合规指标"""
        start_time, end_time = cls._get_date_range(period, stats_date)

        # 1. 违规内容统计
        violation_stats = {
            "违规职位数": JobAuditRecord.objects.filter(
                audit_result=2, audit_time__range=(start_time, end_time)
            ).count(),
            # "违规聊天消息数": ChatMessage.objects.filter(
            #     status=2, send_time__range=(start_time, end_time)
            # ).count(),
            # 违规图片数：当前项目中暂无图片审核记录模型，暂时设为0
            "违规图片数": 0,
            "审核通过率": cls._calculate_audit_pass_rate(start_time, end_time)
        }

        # 2. 违规类型分布（基于Violation的word_type，通过JobAuditRecord的word_types字段统计）
        violation_type_stats = dict(
            JobAuditRecord.objects.filter(
                audit_result=2, audit_time__range=(start_time, end_time)
            ).values("word_types").annotate(count=Count("id"))  # word_types存储如"虚假招聘,广告引流"
        )

        return {**violation_stats, "违规类型分布": violation_type_stats}

    @classmethod
    def _calculate_audit_pass_rate(cls, start_time, end_time):
        """计算审核通过率（合规数/总审核数）"""
        total_audit = JobAuditRecord.objects.filter(audit_time__range=(start_time, end_time)).count()
        pass_audit = JobAuditRecord.objects.filter(
            audit_result=1, audit_time__range=(start_time, end_time)
        ).count()
        return round(pass_audit / total_audit * 100, 2) if total_audit > 0 else 0

    @classmethod
    def calculate_interaction_stats(cls, period, stats_date):
        """计算互动指标"""
        start_time, end_time = cls._get_date_range(period, stats_date)

        # 1. 聊天相关统计
        # chat_stats = {
        #     "聊天消息总数": ChatMessage.objects.filter(send_time__range=(start_time, end_time)).count(),
        #     # 已读消息数：当前ChatMessage模型无is_read字段，使用已发送状态的消息数
        #     "已读消息数": ChatMessage.objects.filter(
        #         send_time__range=(start_time, end_time), status=1
        #     ).count(),
        #     "企业回复率": cls._calculate_company_reply_rate(start_time, end_time),
        #     # 求职者响应率：当前项目中暂无相关字段，暂时设为0
        #     "求职者响应率": 0
        # }

        # 2. 职位转化统计
        # 使用Job模型的view_count字段统计浏览量（需要累加）
        total_views = Job.objects.filter(created_at__range=(start_time, end_time)).aggregate(
            total=Sum('view_count')
        )['total'] or 0
        conversion_stats = {
            "职位浏览量": total_views,
            # 浏览→投递转化率：当前项目中暂无简历投递模型，暂时设为0
            "浏览→投递转化率": 0
        }
        # ** chat_stats
        return { **conversion_stats}

    # @classmethod
    # def _calculate_company_reply_rate(cls, start_time, end_time):
    #     """企业回复率（企业主动回复数/求职者消息数）"""
        # user_messages = ChatMessage.objects.filter(
        #     send_time__range=(start_time, end_time), sender_type=2  # 2=求职者发送
        # ).count()
        # company_replies = ChatMessage.objects.filter(
        #     send_time__range=(start_time, end_time), sender_type=1  # 1=企业发送
        # ).count()
        # return round(company_replies / user_messages * 100, 2) if user_messages > 0 else 0

    # @classmethod
    # def _calculate_user_response_rate(cls, start_time, end_time):
    #     """求职者响应率（当前项目中暂无相关字段，返回0）"""
    #     # 待后续添加相关模型后实现
    #     return 0

    @classmethod
    def run_stats(cls, period, stats_date=None):
        """执行统计（默认统计当天/当周/当月）"""
        stats_date = stats_date or timezone.now().date()

        # 避免重复统计（根据unique_together约束：period, stats_type, stats_date）
        stats_type = 1  # 综合统计（包含业务、合规、互动三种指标）
        if DataStats.objects.filter(period=period, stats_type=stats_type, stats_date=stats_date).exists():
            logger.warning(f"已存在{cls.get_period_display(period)}-{stats_date}的统计数据，跳过重复统计")
            return

        # 计算各类型指标
        business_data = cls.calculate_business_stats(period, stats_date)
        compliance_data = cls.calculate_compliance_stats(period, stats_date)
        interaction_data = cls.calculate_interaction_stats(period, stats_date)

        # 保存统计结果（stats_type=1表示业务指标，但实际存储了三种指标数据）
        DataStats.objects.create(
            period=period,
            stats_type=stats_type,  # 综合统计（包含业务、合规、互动三种指标）
            stats_date=stats_date,
            business_data=business_data,
            compliance_data=compliance_data,
            interaction_data=interaction_data
        )
        logger.info(f"成功生成{cls.get_period_display(period)}-{stats_date}的统计数据")

    @staticmethod
    def get_period_display(period):
        """获取统计周期中文描述"""
        period_map = {1: "日", 2: "周", 3: "月"}
        return period_map.get(period, "未知")